import { useRequest } from 'ahooks';
import { useSearchParams } from 'next/navigation';
import { createContext, useEffect, useState, useRef, useMemo } from 'react';
import {
  DownOutlined,
  FrownFilled,
  FrownOutlined,
  MehOutlined,
  SmileOutlined,
  ReloadOutlined,
  PlusOutlined,
} from '@ant-design/icons';
import type { RadioChangeEvent } from 'antd';
import { Popover, Tooltip } from 'antd';
import { message } from 'antd';
import type { DataNode } from 'antd/es/tree';
import Image from 'next/image';
import { cloneDeep } from 'lodash';
import WorkbenchesIcon from '@/components/workbenches/icons';
import {
  ComponentType,
  TabPosition,
  actionType,
} from '@/components/workbenches/hooks/type';
import { metricTree } from '@/client/api/workbenches';
import { modelGet } from '@/client/api/workbenches';
import { getMetricQueryInfo } from '@/client/api';
interface leftDataSourceType {
  dataSourceId?: string;
  dataSourceData?: any;
  dataSourceQuery?: any;
}
interface IWorkbenchesContext {
  copilotVisible: boolean;
  setCopilotVisible: (val: boolean) => void;
  tabPosition: TabPosition;
  searchValue: string;
  setSearchValue: (val: string) => void;
  changeTabPosition: (val: RadioChangeEvent) => void;
  treeData: DataNode[];
  treeDataFilter: DataNode[];
  defaultSelectedKeys: string[];
  setDefaultSelectedKeys: () => void;
  leftDataSource: leftDataSourceType;
  onSelect: () => void;
  activeKey: string,
  setActiveKey: (string: string) => void,
  items: any[],
  setItems: (ary: any[]) => void,
  loading: boolean;
  newTabIndex: number,
  onChange: (v: string) => void,
  onEdit: (targetKey: string, action: actionType) => void,
  currentItem: any,
  graphValue: any,
  addTabs: (info: any, type: ComponentType) => void,
  getCurrentItemChange: (id?: string | null) => void;
  setCurrentItemChange: (v: any) => void;
  clearChange: () => void,
  canvasResizeChange: () => void,
  delTabChange: (data: any) => void,
  saveState: any,
  setSaveState: (data: any) => void,
}

const WorkbenchesContext = createContext<IWorkbenchesContext>({
  copilotVisible: false,
  setCopilotVisible: () => { },
  tabPosition: 'all',
  searchValue: '',
  setSearchValue: () => { },
  changeTabPosition: () => { },
  treeData: [],
  treeDataFilter: [],
  defaultSelectedKeys: [],
  setDefaultSelectedKeys: () => { },
  leftDataSource: {},
  onSelect: () => { },
  activeKey: '',
  setActiveKey: () => { },
  items: [],
  setItems: () => { },
  newTabIndex: 0,
  loading: false,
  onChange: () => void 0,
  onEdit: () => void 0,
  currentItem: null,
  graphValue: null,
  addTabs: () => void 0,
  getCurrentItemChange: () => void 0,
  setCurrentItemChange: () => void 0,
  clearChange: () => { },
  canvasResizeChange: () => { },
  delTabChange: () => { },
  saveState: {},
  setSaveState: () => { },
});

const WorkbenchesContextProvider = ({ children }: { children: React.ReactElement }) => {
  const [copilotVisible, setCopilotVisible] = useState(false);
  const [tabPosition, setTabPosition] = useState<TabPosition>('all');
  const [searchValue, setSearchValue] = useState<string>('');
  const changeTabPosition = (e: RadioChangeEvent) => {
    setTabPosition(e.target.value);
  };
  const [treeData, setTreeData] = useState<DataNode[]>([
    // {
    //   title: '192.168.1.1',
    //   key: '0-0',
    //   icon: <WorkbenchesIcon type='starrocks' />,
    //   children: [
    //     {
    //       title: 'noahx',
    //       key: '0-0-0',
    //       icon: <WorkbenchesIcon type='库' />,
    //       children: [
    //         {
    //           title: '表',
    //           key: '0-0-0-0',
    //           icon: <WorkbenchesIcon type='文件夹开启' />,
    //           children: [
    //             {
    //               title: 'customer',
    //               key: '0-0-0-0-0',
    //               icon: <WorkbenchesIcon type='表' />,
    //               type: ComponentType.TABLE,
    //             },
    //             {
    //               title: 'orders',
    //               key: '0-0-0-0-1',
    //               icon: <WorkbenchesIcon type='表' />,
    //               type: ComponentType.TABLE,
    //             },
    //           ],
    //         },
    //         {
    //           title: '视图',
    //           key: '0-0-0-1',
    //           icon: <WorkbenchesIcon type='文件夹开启' />,
    //         },
    //       ],
    //     },
    //     {
    //       title: '模型',
    //       key: '0-0-1',
    //       icon: <WorkbenchesIcon type='模型文件夹' />,
    //       children: [
    //         {
    //           title: '全部',
    //           key: '0-0-1-0',
    //           icon: <WorkbenchesIcon type='文件夹开启' />,
    //         },
    //         {
    //           title: '我的',
    //           key: '0-0-1-1',
    //           icon: <WorkbenchesIcon type='文件夹开启' />,
    //           children: [
    //             {
    //               title: 'customer',
    //               key: '0-0-1-1-0',
    //               icon: <WorkbenchesIcon type='模型' />,
    //               type: ComponentType.MODEL,
    //             },
    //             {
    //               title: 'orders',
    //               key: '0-0-1-1-1',
    //               icon: <WorkbenchesIcon type='模型' />,
    //               type: ComponentType.MODEL,
    //             },
    //           ],
    //         },
    //       ],
    //     },

    //     {
    //       title: '查询',
    //       key: '0-0-2',
    //       icon: <WorkbenchesIcon type='查询文件夹' />,
    //       children: [
    //         {
    //           title: 'noahx 2025-4-9 12:23:45',
    //           key: '0-0-2-0',
    //           icon: <WorkbenchesIcon type='查询' />,
    //           type: ComponentType.QUERY,
    //         },
    //       ],
    //     },
    //   ],
    // },
    // {

    //   title: '财务系统',
    //   key: '0-1',
    //   icon: <WorkbenchesIcon type='starrocks' />,
    // }
  ]);

  const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(['']);

  interface itemsProps {
    label: string,
    key: string,
    type: ComponentType,
  }
  const [activeKey, setActiveKey] = useState('');
  const [items, setItems] = useState([
    // { label: 'model', key: '0-0-1-1-0', type: 'model' }
  ] as itemsProps[]);
  function processData(arr) {
    return arr.filter((i: any) => !['View', 'MaterializedView'].includes(i.nodeType)).map((obj: any) => {
      const { id, name, nodeType, children, accelerationEnabled, } = obj;
      const newObj = {
        ...obj,
        key: id,
        title: name,
        type: nodeType,
      };
      newObj.title = () => {
        return name.length > 16 ? (
          <Tooltip placement="left" title={name}>
            <div className='flex items-center'>
              <span className='mx-2 w-[130px] overflow-hidden whitespace-nowrap text-ellipsis'>{name}</span>
              {accelerationEnabled && <WorkbenchesIcon type='发布' />}
            </div>
          </Tooltip>
        ) : (
          <div className='flex items-center'>
            <span className='mx-2 w-[130px] overflow-hidden whitespace-nowrap text-ellipsis'>{name}</span>
            {accelerationEnabled && <WorkbenchesIcon type='发布' />}
          </div>
        );
      }
      if (nodeType === 'Datasource') {
        newObj.icon = <WorkbenchesIcon type='starrocks' />;
      } else if (nodeType === 'Schema') {
        newObj.icon = <WorkbenchesIcon type='库' />;
      } else if (nodeType === 'Model') {
        newObj.icon = <WorkbenchesIcon type='模型' />;
      } else if (nodeType === 'Query') {
        newObj.icon = <WorkbenchesIcon type='查询' />;
      } else if (nodeType === 'Table') {
        newObj.icon = <WorkbenchesIcon type='表' />;
      } else if (nodeType === 'View') {
        newObj.icon = <WorkbenchesIcon type='视图' />;
      } else if (nodeType === 'MaterializedView') {
        newObj.icon = <WorkbenchesIcon type='物化视图' />;
      } else if (nodeType === 'Model_Catalog') {
        newObj.icon = <WorkbenchesIcon type='模型文件夹' />;
      } else if (nodeType === 'Query_Catalog') {
        newObj.icon = <WorkbenchesIcon type='查询文件夹' />;
      }
      if (children && children?.length > 0) {
        newObj.children = processData(children);
      }
      return newObj;
    });
  }
  function filterTreeData(nodes: any[], options: { showType: TabPosition }) {
    if (!Array.isArray(nodes) || nodes.length === 0) {
      return [];
    }

    // 处理不同展示类型的配置
    const { showType } = options;
    let includeTypes = [];
    let includeParents = false;

    switch (showType) {
      case 'all':
        return [...nodes];
      case 'data':
        includeTypes = ['Table', 'View', 'MaterializedView'];
        includeParents = true;
        break;
      case 'model':
        includeTypes = ['Model'];
        includeParents = true;
        break;
      case 'query':
        includeTypes = ['Query'];
        includeParents = true;
        break;
      default:
        return [];
    }

    return nodes.reduce((result, node) => {
      if (includeTypes.includes(node.nodeType)) {
        result.push({ ...node });
        return result;
      }

      if (node.children && Array.isArray(node.children) && node.children.length > 0) {
        const filteredChildren = filterTreeData(node.children, options);

        if (filteredChildren.length > 0 && includeParents) {
          const newNode = { ...node, children: filteredChildren };
          result.push(newNode);
        }
        else if (filteredChildren.length > 0) {
          result.push(...filteredChildren);
        }
      }

      return result;
    }, []);
  }

  function searchTreeData(nodes: any[], searchText: string) {
    if (!Array.isArray(nodes) || nodes.length === 0 || !searchText) {
      return [...nodes];
    }

    const normalizedSearchText = searchText.toLowerCase();

    return nodes.reduce((result, node) => {
      // 检查当前节点是否匹配搜索文本
      const nodeMatches = node.name?.toLowerCase().includes(normalizedSearchText);

      if (nodeMatches) {
        result.push({ ...node });
        return result;
      }

      // 如果当前节点不匹配，检查子节点
      if (node.children && Array.isArray(node.children) && node.children.length > 0) {
        const filteredChildren = searchTreeData(node.children, searchText);

        if (filteredChildren.length > 0) {
          // 保留父节点结构，只包含匹配的子节点
          const newNode = { ...node, children: filteredChildren };
          result.push(newNode);
        }
      }

      return result;
    }, []);
  }

  function filterAndSearchTreeData(nodes: any[], options: { showType: TabPosition, searchText: string }) {
    const { showType, searchText } = options;

    // 先按类型筛选
    let filteredNodes = filterTreeData(nodes, { showType });

    // 再按文本搜索
    return searchTreeData(filteredNodes, searchText);
  }

  const treeDataFilter = useMemo(() => {
    return filterAndSearchTreeData(treeData, { showType: tabPosition, searchText: searchValue });
  }, [tabPosition, treeData, searchValue]);

  const { run: initData } = useRequest(
    async () => {
      return await metricTree();
    },
    {
      manual: true,
      onSuccess: (res: any) => {
        const { code, data } = res.data || {};
        if (code == 0) {
          const result = processData(data || [])
          return setTreeData(result);
        } else {
          message.error(res.data.msg || '查询失败!');
        }
        return setTreeData([])
      },
      debounceWait: 10,
    },
  );
  useEffect(() => {
    initData();
  }, []);
  const newTabIndex = useRef(0);
  const [loading, setLoading] = useState(false);

  const addTabs = async (info: any, addType: ComponentType | null = null) => {
    setLoading(true);
    if (addType) {
      info.node = {
        title: '',
        key: `node-${Date.now()}`,
        type: addType,
      }
      // 添加模型tab将左侧树选择数据源信息带过来
      if (ComponentType.MODEL == addType) {
        info.node = {
          ...info.node,
          ...leftDataSource,
        }
      }
      // 查询传参
      if (ComponentType.QUERY == addType) {
        info.node = {
          ...info.node,
          ...leftDataSource,
        }
      }
    }

    const { name, key, type, modelInfo } = info?.node || {};

    const haveTabIndex: number | undefined = items.findIndex((item) => item.key == key);
    // console.log('haveTab', items, haveTabIndex, info?.node)
    // console.log('t3232ype', info, type)
    if ([ComponentType.TABLE, ComponentType.MODEL, ComponentType.QUERY, ComponentType.VIEW, ComponentType.MATERIALIZED_VIEW].includes(type)) {
      setActiveKey(key);
      const newPanes = cloneDeep(items);
      let params: any = { label: name, key, type }
      if (ComponentType.MODEL == type && info.id && !modelInfo) {
        const { data } = await modelGet({ id: info.id.split('_')[1] });
        if (data?.code != 0 || !data.data) {
          return message.error(data?.msg || '查询失败!')
        }
        params.modelInfo = data.data;
        const { datasourceId } = data.data as any;
        const dataSource: any = treeData.find((i: any) => i.id == datasourceId)
        params.dataSourceId = dataSource.id;
        params.dataSourceData = dataSource.children.find((i: any) => i.nodeType == 'Schema');
        params.dataSourceQuery = dataSource.children.find((i: any) => i.nodeType == 'Query_Catalog');
      } else {
        const { dataSourceId, dataSourceData, dataSourceQuery, modelInfo,
          metricModelTables, metricModelTableRelationships,
        } = info?.node || {};
        params = {
          ...params,
          dataSourceId, dataSourceData, dataSourceQuery, modelInfo,
          metricModelTables, metricModelTableRelationships,
        }
      }
      if (haveTabIndex == -1) {
        newPanes.push(params);
      } else {
        newPanes[haveTabIndex] = params;
      }
      setItems(newPanes);
    } else {
      setActiveKey('');
    }
    setLoading(false);
  }
  const getCurrentItemChange = async (id?: string) => {
    setLoading(true);
    const { key, type, } = currentItem as any || {};
    const haveTabIndex: number | undefined = items.findIndex((item) => item.key == key);
    if ([ComponentType.TABLE, ComponentType.MODEL, ComponentType.QUERY].includes(type as ComponentType)) {
      setActiveKey(key as string);
      const newPanes = cloneDeep(items);
      let params: any = { ...currentItem }
      if (ComponentType.MODEL == type && key) {
        const par = { id: key.split('_')[1] };
        if (id) {
          par.id = id.split('_')[1];
          setActiveKey(id as string);
        }
        const { data } = await modelGet(par);
        if (data?.code != 0 || !data.data) {
          return message.error(data?.msg || '查询失败!');
        }
        if (id) {
          params.key = id;
        }

        params.modelInfo = data.data;
        const { datasourceId } = data.data as any;
        const dataSource: any = treeData.find((i: any) => i.id == datasourceId)
        params.dataSourceId = dataSource.id;
        params.dataSourceData = dataSource.children.find((i: any) => i.nodeType == 'Schema');
        params.dataSourceQuery = dataSource.children.find((i: any) => i.nodeType == 'Query_Catalog');
      }
      if (ComponentType.QUERY == type && key) {
        const par = { id: key.split('_')[1] };
        if (id) {
          par.id = id.split('_')[1];
          setActiveKey(id as string);
        }
        const { data } = await getMetricQueryInfo(par);
        if (data?.code != 0 || !data.data) {
          return message.error(data?.msg || '查询失败!');
        }
        params.key = id;
        params.label = data.data.queryName;
        params.modelInfo = data.data;
      }
      // console.log('params3443', params)
      if (haveTabIndex == -1) {
        newPanes.push(params);
      } else {
        newPanes[haveTabIndex] = params;
      }
      setItems(newPanes);
    } else {
      setActiveKey('');
    }
    setLoading(false);
    initData();
  }
  const setCurrentItemChange = async (data: any) => {
    const { key, type, dataSourceId, } = currentItem as any || {};
    if (!dataSourceId) {
      return message.error('请先选择数据源!')
    }
    setLoading(true);
    const haveTabIndex: number | undefined = items.findIndex((item) => item.key == key);
    setActiveKey(key as string);
    const newPanes = cloneDeep(items);
    let params: any = { ...currentItem, }
    if (ComponentType.MODEL == type && key) {
      params.modelInfo = {
        ...params.modelInfo,
        ...data,
      };
      const dataSource: any = treeData.find((i: any) => i.id == dataSourceId)
      params.dataSourceId = dataSource.id;
      params.dataSourceData = dataSource.children.find((i: any) => i.nodeType == 'Schema');
      params.dataSourceQuery = dataSource.children.find((i: any) => i.nodeType == 'Query_Catalog');
    }
    if (haveTabIndex == -1) {
      newPanes.push(params);
    } else {
      newPanes[haveTabIndex] = params;
    }
    setItems(newPanes);
    setLoading(false);
  }
  const delTabChange = (data: any) => {
    initData();
    if (items?.length) {
      const newPanes = items.filter((item) => item.key != data.key);
      setItems(newPanes);
      if (activeKey == data.key && newPanes?.length) {
        setActiveKey(newPanes[0]?.key);
      }
    }
  }
  const [leftDataSource, setLeftDataSource] = useState<leftDataSourceType>({});
  const onSelect = async (selectedKeys: any, info: any) => {
    const id = info.node?.id;
    if (id && info.node?.nodeType == 'Datasource') {
      const params: leftDataSourceType = {
        dataSourceId: id,
      }
      if (info.node?.children?.length) {
        params.dataSourceData = info.node.children.find((i: any) => i.nodeType == 'Schema');
        params.dataSourceQuery = info.node.children.find((i: any) => i.nodeType == 'Query_Catalog');
      }
      setLeftDataSource(params);
      return
    }
    if (!selectedKeys?.length) {
      setDefaultSelectedKeys(defaultSelectedKeys);
    } else {
      setDefaultSelectedKeys(selectedKeys);
    }
    await addTabs({ ...info, id: info.node.id });
  }
  const currentItem = useMemo(() => {
    return cloneDeep(items).find(i => i.key == activeKey);
  }, [activeKey, items]);

  const onChange = async (newActiveKey: string) => {
    // setActiveKey(newActiveKey);
    await addTabs({ node: items.find(i => i.key == newActiveKey) });
  };

  const add = () => {
    const newActiveKey = `newTab${newTabIndex.current++}`;
    const newPanes = [...items];
    newPanes.push({ label: 'New Tab', key: newActiveKey });
    setItems(newPanes);
    setActiveKey(newActiveKey);
  };

  const remove = (targetKey: string) => {
    let newActiveKey = activeKey;
    let lastIndex = -1;
    items.forEach((item, i) => {
      if (item.key === targetKey) {
        lastIndex = i - 1;
      }
    });
    const newPanes = items.filter(item => item.key !== targetKey);
    if (newPanes.length && newActiveKey === targetKey) {
      if (lastIndex >= 0) {
        newActiveKey = newPanes[lastIndex].key;
      } else {
        newActiveKey = newPanes[0].key;
      }
    }
    setItems(newPanes);
    setActiveKey(newActiveKey);
  };

  const onEdit = (targetKey: string, action: actionType) => {
    if (action === 'add') {
      add();
    } else {
      remove(targetKey);
    }
  };

  let graphValue: any = useRef(null);
  const clearChange = () => {
    setTabPosition('all');
    setSearchValue('');
    setDefaultSelectedKeys([])
    setLeftDataSource({});
    initData();
  }
  const canvasResizeChange = () => {
    if (graphValue.current) {
      //  重新设置画布大小  
      const container = document.querySelector('.svg-model') as HTMLDivElement;
      if (container) {
        graphValue.current.resize(container.offsetWidth < 1000 ? 1362 : container.offsetWidth, container.offsetHeight)
      }
    }
  }
  useEffect(() => {
    // 关闭copilot对话
    if (!copilotVisible) {
      canvasResizeChange();
    }
  }, [copilotVisible])

  const [saveState, setSaveState] = useState({});
  const contextValue = {
    copilotVisible,
    setCopilotVisible,
    tabPosition,
    searchValue,
    setSearchValue,
    changeTabPosition,
    treeData,
    treeDataFilter,
    defaultSelectedKeys,
    setDefaultSelectedKeys,
    leftDataSource,
    onSelect,
    activeKey,
    setActiveKey,
    items,
    setItems,
    loading,
    newTabIndex,
    onChange,
    onEdit,
    currentItem,
    graphValue,
    addTabs,
    getCurrentItemChange,
    setCurrentItemChange,
    clearChange,
    canvasResizeChange,
    delTabChange,
    saveState,
    setSaveState,
  };
  return <WorkbenchesContext.Provider value={contextValue}>{children}</WorkbenchesContext.Provider>;
};

export { WorkbenchesContext, WorkbenchesContextProvider };
